﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
using Metro.Kashikoi.ServiceContract.Security;
using Metro.Kashikoi.Common.ExceptionHandling;

namespace Metro.Kashikoi.Service.Common.Security
{
    /*
<system.serviceModel> 
  <bindings>
  <wsHttpBinding>
      <binding name="Binding1">
        <security mode="Message">
          <message clientCredentialType="UserName" />
        </security>
      </binding>
    </wsHttpBinding>
  </bindings>
  <behaviors> 
    <behavior name="BahaviorName">
        <serviceCredentials>
          <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="Microsoft.ServiceModel.Samples.CalculatorService.CustomUserNameValidator, service" />
        </serviceCredentials>
    </behavior>
  </behaviors> 
</system.serviceModel>
    */
    //ServiceSecurityContext.Current.PrimaryIdentity


    public class AuthenticateMananger : UserNamePasswordValidator
    {
        private static readonly Dictionary<string, Token> session = new Dictionary<string, Token>();

        #region UserNamePasswordValidator Members

        /// <summary>
        /// When overridden in a derived class, validates the specified username and password.
        /// </summary>
        /// <param name="userName">The username to validate.</param>
        /// <param name="password">The password to validate.</param>
        public override void Validate(string userName, string password)
        {
            if (string.IsNullOrEmpty(userName) || null == password)
            {
                throw new ArgumentNullException();
            }

            bool validated = false;
            lock ((session as ICollection).SyncRoot)
            {
                if (session.ContainsKey(userName))
                {
                    Token token = session[userName];
                    if (!token.IsTimeout())
                    {
                        if (token.Password == password)
                        {
                            validated = true;
                            token.LastAccess = DateTime.Now;
                        }
                    }
                    else
                    {
                        session.Remove(userName);
                    }
                }
            }
            if (!validated)
            {
                throw new SecurityException();
            }
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Registers the user.
        /// </summary>
        /// <param name="userName">The username.</param>
        /// <param name="password">The password.</param>
        public static void RegisterUser(string userName, string password)
        {

            lock ((session as ICollection).SyncRoot)
            {
                if (session.ContainsKey(userName))
                {
                    session[userName].LastAccess = DateTime.Now;
                }
                else
                {
                    session.Add(userName, new Token
                    {
                        Password = password.GetHashCode().ToString(),
                        LastAccess = DateTime.Now
                    });
                }
            }
        }

        #endregion

        private class Token
        {
            public int Id { get; set; }
            public DateTime LastAccess { get; set; }
            public string Password { get; set; }
            public bool IsTimeout()
            {
                return (DateTime.Now - LastAccess).TotalSeconds < 1800;
            }
        }
    }
}
